Lousy map/texture generator.
Introduction
This was originally written for and sent to Wilby diskmag (along with a few more articles) but unfortunately none of them have appeared or are likely to appear in the near future. All seems quiet in the Wilby part of the globe and with no response to say that the articles ever had arrived, I have decided to publish them here. You (un)lucky people. ;)
The code itself.
Here is the entire program which should be assembled as a .COM (tiny model) program.
.model tiny
.code
.286
org 256
go: mov al,13h ; [1]
int 10h
mov ax,0A000h
mov DS,ax ; [2]
mov dx,3C8h
out dx,al
inc dx
rgb: ror ax,2 ; [3]
out dx,al
rol ax,1 ; [4]
out dx,al
rol ax,1 ; [5]
out dx,al
inc ax ; [6]
loop rgb ; [7]
gen: mov [bx],al ; [8]
add ax,bx ; \
aad 13 ; [9]
inc bx ; /
jnz gen ; [10]
mov cl,30 ; [11]
arc: mov al,[bx]
adc al,[bx+1]
shr al,1
adc al,[bx+320]
shr al,1
mov [bx],al ; [12]
inc bx ; \
jnz arc ; / [13]
loop arc ; [14]
int 16h ; [15]
mov ax,3
int 10h
ret ; [16]
end go
"Groovy"
First of all, because it is intended to be a .COM program I have assumed that some registers will be set to certain values upon start up. These values are:-
ax = 00xx
bx = 0000
cx = 00FF
The AH register is assumed to be 00h, this saves 1 byte over a normal MOV AX,0013h instruction.
go: mov al,13h ; [1]
The DS segment register is loaded with the paragraph address of the video memory. Because AX=A000 hex we can use the AL=00 to set the PEL index register without needing to perform a MOV AL,00 instruction saving 2 bytes.
mov DS,ax ; [2]
mov dx,3C8h
out dx,al
The palette is set up using a red=n DIV 4, green=n DIV 2 and blue=n loop. Bits 15 and 14 of the AX register are used as temporary storage for the DIV 4 and DIV 2 steps.
rgb: ror ax,2 ; [3] n DIV 4
out dx,al
rol ax,1 ; [4] n DIV 2
out dx,al
rol ax,1 ; [5] n
out dx,al
The palette generation loop assumes that the CX register is 00FF hex. This saves 3 bytes (MOV CX,xxxx) but means only the first 255 colours are set.
loop rgb ; [7]
The map/texture generation loop is next. It's only 9 bytes and does a okay (ish) job at filling the entire 64kb with random values. It assumes the BX=0000 on entry and will exit with BX=0000. In fact all the following loops uses this BX=0000..FFFF wrap to avoid having to reinit the BX register.
gen: mov [bx],al ; [8] write AL to the buffer
add ax,bx ; \
aad 13 ; [9] the 5 byte 'random' generator
inc bx ; /
jnz gen ; [10]
Okay, so it doesn't look much like a map/texture at the present time, more like a ROM dump to the screen, or perhaps a rainbow coloured snow scene. ;) It has no local cohesion, it needs some kinda shaping function in order to make neighbouring pixels look like they contribute something to the overall image.
This is where the smoothing operation comes in. It helps to give the 'random snow' some apparent purpose. Instead of chaos we end up with a nice cloud/map-like image. The following smooth loop takes the pixel to the right, the pixel below and the current pixel then performs a dodgy average on them. I've used ADC to introduce a little bit more random-ness into the smooth operation. The smooth operation repeats 30 times in order to help push the random spikes of the map outwards into the neighbouring pixels. You can of course experiment with different repeat values to create very smooth or spiky maps.
mov cl,30 ; [11]
arc: mov al,[bx]
adc al,[bx+1]
shr al,1
adc al,[bx+320]
shr al,1
mov [bx],al ; [12] write new the 'averaged' pixel
inc bx ; \
jnz arc ; / [13]
loop arc ; [14] repeat CX times
Because AX=00xx from the AAD 13 instruction at step [9], we don't need to use MOV AH,00 for the key-wait INT 16h below. That AAD instruction always gives AH=00 (and also helps to randomise things too ;).
int 16h ; [15]
The normal text-mode switch and exit then occurs.
mov ax,3
int 10h
ret ; [16]
Final words
So it ain't going to win any prizes for texture generation, but it might be good enough (or perhaps some part(s) of it) for a small 256, 512 or 1kb intro. In fact the palette generation might be good enough to be used in a voxel landscape or similiar effect.
Happy mapping...